#ifndef HTTP_CONNECTION_H
#define HTTP_CONNECTION_H

#include <tcp_client.h>

#include <string>
#include <sstream>

class HttpConnection;
class HttpRequest{
	public:
		friend class HttpConnection;
		HttpRequest(const std::string& path, const std::map<std::string, std::string>& get_variables):
			path(path), get_variables(get_variables){
		}
	private:
		std::string path;
		std::map<std::string, std::string> get_variables;
};
class HttpConnection:public TcpClientConnection{
	public:
		HttpConnection(const std::string& host):TcpClientConnection(host, 80), host(host){
			
		}
		void send(const HttpRequest& request){
			std::string request_string;
			request_string+="GET "+request.path+(request.get_variables.empty()?"":"?");
			for(std::map<std::string, std::string>::const_iterator itr=request.get_variables.begin();
				itr!=request.get_variables.end(); ++itr){
				//std::string urlencoded=urlEncode(itr->second);
				//std::cout<<"urlencoded:"<<urlencoded<<std::endl;
				request_string+=itr->first+"="+urlEncode(itr->second)+(itr==--request.get_variables.end()?"":"&");
			}
			request_string+=" HTTP/1.1\nHost: "+host+"\n\n";
			std::cout<<"HttpConnection::send()-request_string:"<<request_string<<std::endl;
			try{
				TcpClientConnection::send(request_string);
			}
			catch(UnableToSend& x){
				g_warning("HttpConnection::Send()-%s", x.what());
			}
		}
		std::string recv(){
			std::string response;
			std::string data;
			response=TcpClientConnection::recv();
			
			std::cout<<"HttpConnection::recv():"<<response<<std::endl;
			
			std::string::size_type pos=response.find("\r\n\r\n");
			if(pos==std::string::npos){
				//throw InvalidHttpResponse(http_response);
				g_warning("HttpConnection::recv()-no data to receive"); 
				return data;
			}
			data=response.substr(pos+4);
			return data;
		}
		static std::string urlEncode(const std::string& s){
			std::string result;
			for(std::string::const_iterator itr=s.begin(); itr!=s.end(); ++itr){
				if(*itr>='a' && *itr<='z' || *itr>='A' && *itr<='Z' || *itr>='0' && *itr<='9'){
					result+=*itr;
				}
				else if(*itr==' '){
					result+="+";
				}
				else if(*itr=='&'){
					result+=*itr;
				}
				else{
					std::stringstream ss;
					std::string hex;
					ss.width(2);
					ss.fill('0');
					ss<<std::hex<<(int)*itr;
					hex=ss.str();
					result+="%"+hex;
				}
			}
			return result;
		}
	private:
		std::string host;
};
HttpConnection& operator<<(HttpConnection& conn, const HttpRequest& r){
	conn.send(r);
	return conn;
}
HttpConnection& operator>>(HttpConnection& conn,  std::string& s){
	s=conn.recv();
	return conn;
}
#endif
